

from django.contrib.auth import authenticate, get_user_model
from django.utils.translation import ugettext as _
from rest_framework import serializers
from rest_framework_jwt.compat import Serializer
import django_redis
from django.contrib.auth import authenticate,get_user_model
from django.utils.translation import ugettext as _
from rest_framework import serializers
from rest_framework_jwt.compat import Serializer

from rest_framework_jwt.settings import api_settings
from rest_framework_jwt.compat import get_username_field, PasswordField
import re
from .utils import get_user_obj_by_account
from .models import User
from rest_framework_jwt.settings import api_settings


User = get_user_model()
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
jwt_get_username_from_payload = api_settings.JWT_PAYLOAD_GET_USERNAME_HANDLER

from django.contrib.auth.hashers import make_password

class CustomJSONWebTokenSerializer(Serializer):
    def __init__(self, *args, **kwargs):
        """
        Dynamically add the USERNAME_FIELD to self.fields.
        """
        super(CustomJSONWebTokenSerializer, self).__init__(*args, **kwargs)

        self.fields[self.username_field] = serializers.CharField()
        self.fields['password'] = PasswordField(write_only=True)
        self.fields['ticket'] = PasswordField(write_only=True)
        self.fields['randstr'] = PasswordField(write_only=True)

    @property
    def username_field(self):
        return get_username_field()

    def validate(self, attrs):
        credentials = {
            self.username_field: attrs.get(self.username_field),
            'password': attrs.get('password'),
            'ticket': attrs.get('ticket'),
            'ranstr': attrs.get('randstr')

        }

        if all(credentials.values()):
            user = authenticate(self.context['request'],**credentials)

            if user:
                if not user.is_active:
                    msg = _('User account is disabled.')
                    raise serializers.ValidationError(msg)

                payload = jwt_payload_handler(user)

                return {
                    'token': jwt_encode_handler(payload),
                    'user': user
                }
            else:
                msg = _('Unable to log in with provided credentials.')
                raise serializers.ValidationError(msg)
        else:
            msg = _('Must include "{username_field}" and "password".')
            msg = msg.format(username_field=self.username_field)
            raise serializers.ValidationError(msg)

# 注册的序列化器
class RegisterSerializer(serializers.ModelSerializer):
    #手机号、密码、验证码
    sms_code = serializers.CharField(max_length=6,min_length=4,write_only=True)
    # password = serializers.CharField(min_length=16)  #自己生民的序列化器字段会覆盖ModelSerializer自动生成的字段
    token = serializers.CharField(max_length=256,read_only=True)
    class Meta:
        model = User  #password
        fields = ['id','username','phone','password','sms_code','token']
        extra_kwargs = {
            'password':{
                'write_only':True,
            },
            'phone':{
                'write_only':True,
            },
            # 'sms_code':{
            #     'write_only':True,
            # },
            'username':{
                'read_only':True,
            },
            'id':{
                'read_only':True,
            },
        }
    # def validate_password(self,value):
    #     #复杂的密码规则校验
    #     return value
    def validate_phone(self,phone):
        #手机号格式校验
        if not re.match('1\d{10}',phone):
            raise serializers.ValidationError('手机号格式有误')
        # 手机号唯一性校验
        ret = get_user_obj_by_account(phone)
        if ret:
            raise serializers.ValidationError('手机号已经被注册了！！！')
        return phone

    # todo 验证  sms_code
    def validate(self,data):

        # 请求发送过来的验证码和手机号
        phone = data.get('phone')
        sms_code = data.get('sms_code')

        # redis 数据库中获取村的对应手机号的验证码
        conn = django_redis.get_redis_connection('sms_code')
        redis_code = conn.get(f'sms_{phone}')
        print(redis_code)
        if redis_code:
            redis_code = redis_code.decode()
            if sms_code != redis_code:
                raise serializers.ValidationError('验证码输入有误！！！')
            return data
        else:
            raise serializers.ValidationError('验证码已过期！！！')


    def create(self,validated_data):
        password = validated_data.get('password')
        print('validated_data>>>>>>',validated_data)
        hash_password = make_password(password)

        user = User.objects.create(**{
            'phone':validated_data.get('phone'),
            'password':hash_password,
            'username':validated_data.get('phone'),
        })


        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        user.token = token # 给user对象后赋属性
        return user  # 模型类对象 ，  user.username,user.id,user.phone,user.token









